package com.fulinlin;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.io.resource.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashSet;
import java.util.OptionalInt;
import java.util.Set;

/**
 * @program: github-dns
 * @author: fulin
 * @create: 2021-03-03 17:14
 **/
@Slf4j
@Component
public class GetNewestGithubDns {
    @Autowired
    RedisUtil redisUtil;
    final static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    @Value("${markdown.file.save-path}")
    private String path ;
    @Value("${setKey}")
    private String setKey ;
    @Value("${updateDateKey}")
    private String updateDateKey ;
    public static void main(String[] args) throws IOException {
        GetNewestGithubDns getNewestGithubDns = new GetNewestGithubDns();
        Set<GithubDns> list = getNewestGithubDns.getGithubDns();
        getNewestGithubDns.generateGithubDnsHosts(list);
    }

    public Set<GithubDns> getGithubDns() throws IOException {
        Set<GithubDns> list = initGithubDnsList();
        HttpsUtil.trustEveryone();
        for (GithubDns githubDns : list) {
            log.info("=================================================================");
            log.info("抓取地址为：{} ", githubDns.getIpaddressUrl());
            Document doc = Jsoup.connect(githubDns.getIpaddressUrl()).get();
            Elements elementsByClass = doc.body().getElementsByClass("comma-separated");
            Element first = elementsByClass.first();
            String text = first.child(0).text();
            log.info("抓取dns地址是 {} , 抓取地址：{} ", text, githubDns.getIpaddressUrl());
            githubDns.setIpaddress(text);
            log.info("=================================================================");
        }
        return list;
    }
    public Set getDnsByRedis(){
        Set githubDns = redisUtil.setMembers(setKey);
        if ((githubDns.size() == 0)) {
            try {
                githubDns = getGithubDns();
                updateGitRedis( githubDns);
            } catch (IOException e) {
                log.error(e.getMessage(),e);
            }
        }
        return githubDns;
    }

    public void updateGitRedis( Set githubDns) {
        redisUtil.remove(setKey);
        redisUtil.setCacheSet(setKey, githubDns);
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        redisUtil.set(updateDateKey, sdf.format(date));
    }


    public  void generateGithubDnsHosts(Set<GithubDns> list) {
        String projectPath = System.getProperty("user.dir");
        String readmePath = path + File.separator + "README.md";
        File file = new File(readmePath);
        FileReader fileReader = new FileReader(file);
        String reader = fileReader.readString();
        int i = StringUtils.indexOf(reader, "# update");
        String substring = StringUtils.substring(reader, 0, i);
        FileWriter writer = new FileWriter(file);
        writer.write(substring);
        FileUtil.appendUtf8String("# update " + formatter.format(LocalDateTime.now()) + "\n", file);
        FileUtil.appendUtf8String("```" + "\n", file);
        OptionalInt max = list.stream().map(GithubDns::getIpaddress).mapToInt(String::length).max();
        list.forEach(val -> {
            FileUtil.appendUtf8String(val.getIpaddress() + completionFormatter(val, max.orElse(0)) + val.getHostname() + "\n", file);
        });
        FileUtil.appendUtf8String("```", file);
    }

    private static String completionFormatter(GithubDns githubDns, int maxIpLength) {
        int length = githubDns.getIpaddress().length();
        int completion = maxIpLength - length;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 15 + completion; i++) {
            sb.append(" ");
        }
        return sb.toString();
    }

    private static Set<GithubDns> initGithubDnsList() {
        Resource resource = new ClassPathResource("gitHubDns.txt");
        BufferedReader reader = resource.getReader(Charset.defaultCharset());
        Set<GithubDns> set = new HashSet<>();
        try {
            String line ="";
            while ((line = reader.readLine())!=null){
                set.add(new GithubDns(line));
            }
        } catch (IOException e) {
           log.error("读gitHubDns.txt文件错误",e);
        }
        return set;
    }

    public boolean  writeGithubDnsHosts(){
        boolean flag = false;
        try {
            Set getDnsSet = getGithubDns();
            flag = true;
            for (Object o : getDnsSet) {
                flag = redisUtil.setIsMember(setKey, o);
                if (!flag) {
                    log.info("在 {} 中不存在的是 {}",setKey,o);
                    break;
                }
            }
            if (!flag) {
                updateGitRedis(getDnsSet);
                generateGithubDnsHosts(getDnsSet);
                return  true;
            }
        } catch (IOException e) {
            log.error(e.getMessage(),e);
            return false;
        }
        return flag;
    }
    String getUpdateDate(){
        String date = (String) redisUtil.get(updateDateKey);
        return date;
    }
}
